#pragma once
#include "Entity.h"
#include "RenderSystem.h"
#include "SkeletonJoint.h"

#define DEFAULT_INTERPOLATE_TIME 0.1f

namespace Core{
	class ScriptManager;
}

namespace Graphics{
	struct RenderStates{
		
	};

	class Mesh : public Entity{
	public:
		Mesh(unsigned int modelId);
		Mesh(std::string& filename);

		void render(RenderContext* context, unsigned int inds, unsigned int indOffset);

		Utility::Math::Matrix<4,4> getWorldMatrix();
		unsigned int getModelId() { return m_modelId; }
		float getAnimationMarker() { return m_animationMarker; }
		float getLastAnimationMarker() { return m_lastAnimationMarker; }
		float getCurrentFadeTime() { return m_currentFadeTime; }
		float getFadeTime() { return m_fadeTime; }
		bool isFadeing() { return m_animFadeing; }
		int getCurrentAnimationClipId() { return m_currentAnimationClip; }
		int getLastAnimationClipId() { return m_lastAnimationClip; }

		void rotate(Utility::Math::VectorPos axis, float amount);
		void move(Utility::Math::Vector<float> &dir);
		void scale(float amount);

		void moveForward(float amount);
		void moveUp(float amount);
		void moveRight(float amount);

		void bindToJoint(SkeletonJointPtr joint) { m_jointBound = joint; }

		// Animation controls
		void playAnimation(std::string& name,bool loop,RenderContext* context, float transitionTime = DEFAULT_INTERPOLATE_TIME);
		void stopAnimations();

		void updateAnimation(float dt,RenderContext* context);

		void setWorld(Utility::Math::Matrix<4,4> world);

		void setName(std::string name) { m_name = name; }
		std::string& getName() { return m_name; }
	private:
		// Lua wrappers
		void playAnimation_luaWrap(const char* name,bool loop,float transitionTime = DEFAULT_INTERPOLATE_TIME);
		void moveX_luaWrap(float amount);
		void moveY_luaWrap(float amount);
		void moveZ_luaWrap(float amount);
		void rotateX_luaWrap(float amount);
		void rotateY_luaWrap(float amount);
		void rotateZ_luaWrap(float amount);
		LuaPlus::LuaObject getPosition_luaWrap(LuaPlus::LuaObject dummy);

		bool	m_loopingAnimation,
				m_animFadeing;
		float 	m_animationMarker,
				m_lastAnimationMarker,
				m_animationTime,
				m_timeWarp,
				m_fadeTime,
				m_currentFadeTime;
		int m_currentAnimationClip, 
			m_lastAnimationClip;
		int m_animationFPS;

		Utility::Math::Matrix<4,4> m_world;
		unsigned int m_modelId;
		bool	m_updateWorld,
				m_updateFrontVector,
				m_updateUpVector,
				m_updateLeftVector;

		Utility::Math::Vector<> m_front,m_up,m_right;

		std::string m_name,
					m_modelFile;

		SkeletonJointPtr m_jointBound;

		friend class Core::ScriptManager;
		friend class RenderSystem;
	};
}

typedef boost::shared_ptr<Graphics::Mesh> MeshPtr;